import { debounceFilter } from "@vueuse/shared";
import { nanoid } from "nanoid";
class Node {
  tag = "";
  text = "";
  value = "";
  parent = undefined;
  children = [];
  constructor(opt) {
    this.tag = opt.tag;
    this.text = opt.text;
    this.value = opt.value;
    this.parent = opt.parent;
    this.children = opt.children;
    this.idx = 0;
  }

  findByValue(value) {
    let result = this._getByNode([this], "value", value);

    return result;
  }
  preSlibing() {
    let bos = this.parent.children;

    if (this.idx - 1 >= 0) {
      return bos[this.idx - 1];
    }
    return undefined;
  }

  nextSlibing() {
    let bos = this.parent.children;

    if (this.idx + 1 < bos.length) {
      return bos[this.idx + 1];
    }
    return undefined;
    // this.parent
  }

  _getByNode(node, fileds, value) {
    if (!node) return undefined;

    let childrens = [];
    for (let i = 0; i < node.length; i++) {
      if (node[i][fileds] === value) {
        node[i].idx = i;

        return node[i];
      }

      if (node[i].children && node[i].children.length !== 0) {
        childrens = childrens.concat(node[i].children);
      }
    }

    if (childrens.length !== 0) {
      return this._getByNode(childrens, fileds, value);
    }
  }
}

export class PlistReader {
  constructor(text) {
    this.text = text;

    this.startPoint = 0;

    this.nodeTree = this.readTree();

    return this;
  }

  readTree() {
    let tags = [];

    let texts = [];
    let nodeTree = [];

    while (true) {
      let tx = this.text[this.startPoint];
      if (this.startPoint >= this.text.length) break;
      if (this.text[this.startPoint] === "\n") {
        this.startPoint++;
        continue;
      }

      let endTag = false;

      if (tx === "<") {
        let jumpPoint = this.startPoint + 1;
        while (true) {
          if (this.text[jumpPoint] === ">") {
            let tex = texts.join("");

            if (!endTag) {
              tags.push(tex.split(" ")[0]);
              nodeTree.push(
                new Node({
                  tag: tex.split(" ")[0],
                  text: tex,
                  value: "",
                  children: [],
                })
              );
            } else {
              tex = tex.replace("/", "");

              if (this.text[jumpPoint - 1] === "/") {
                // console.log("closeable:",tex)
                // 获取文本
                let i = jumpPoint - 2;
                let t = [];
                while (true) {
                  if (this.text[i] === "<") {
                    break;
                  }
                  t.push(this.text[i]);

                  i--;
                }
                // console.log('closeable: ',t.reverse().join(''))
                let values = t.reverse().join("");

                nodeTree.push(
                  new Node({
                    tag: values,
                    text: values,
                    value: values,
                    children: [],
                  })
                );
              } else {
                let i = this.startPoint - 1;

                let t = [];
                while (true) {
                  if (this.text[i] === ">") {
                    break;
                  }
                  t.push(this.text[i]);
                  i--;
                }

                let values = t.reverse().join("");

                if (tex === tags[tags.length - 1]) {
                  tags.pop();
                  let count = 0;
                  let idx = -1;

                  for (let j = nodeTree.length - 1; j >= 0; j--) {
                    if (
                      tex === nodeTree[j].tag &&
                      nodeTree[j].children.length === 0
                    ) {
                      idx = j;
                      break;
                    }
                    count++;
                  }

                  if (count == 0) {
                    nodeTree[idx].value = values;
                  } else {
                    let newNode = [];

                    for (let j = 0; j < count; j++) {
                      let curNode = nodeTree.pop();
                      curNode.parent = nodeTree[idx];

                      newNode.unshift(curNode);
                    }
                    nodeTree[idx].children = newNode;
                  }
                }
              }
            }

            texts = [];
            this.startPoint = jumpPoint + 1;
            break;
          }

          if (this.text[jumpPoint] === "/") {
            if (
              this.text[jumpPoint + 1] === ">" ||
              this.text[jumpPoint - 1] === "<"
            ) {
              endTag = true;
            }
          }

          texts.push(this.text[jumpPoint]);
          jumpPoint++;
        }
      } else {
        this.startPoint++;
      }
    }
    return nodeTree;
  }

  findByValue(value) {
    let node = new Node({
      parent: undefined,
      children: this.nodeTree,
      tag: "",
      text: "",
      value: "",
    });
    return node.findByValue(value);
  }

  toPlistRes() {
    let frames = this.findByValue("frames").nextSlibing().children;
    let plistArray = [];
    var reg = /\d+/g;

    for (let i = 0; i < frames.length; i += 2) {
      let key = frames[i];
      let dicts = frames[i + 1].children;
      let plist = {
        key: key.value,
      };

      for (let j = 0; j < dicts.length; j += 2) {
        let dictkey = dicts[j].value;
        let dictValue = dicts[j + 1].value;

        let obj = undefined;
        if (dictkey === "frame" || dictkey === "sourceColorRect") {
          let c = dictValue.match(reg);
          obj = {
            x: parseInt(c[0]),
            y: parseInt(c[1]),
            w: parseInt(c[2]),
            h: parseInt(c[3]),
          };
        } else if (dictkey === "offset") {
          let c = dictValue.match(reg);
          obj = {
            x: parseInt(c[0]),
            y: parseInt(c[1]),
          };
        } else if (dictkey === "sourceSize") {
          let c = dictValue.match(reg);
          obj = {
            w: parseInt(c[0]),
            h: parseInt(c[1]),
          };
        } else if (dictkey === "rotated") {
          obj = dictValue === "false" ? false : true;
        } else {
          obj = dictValue;
        }

        plist = {
          ...plist,
          [dictkey]: obj,
        };
      }

      if (!plist.id) {
        plist.id = nanoid();
      }

      plistArray.push(plist);
    }




    let metadatas = this.findByValue("metadata").nextSlibing().children;
    let metadata = {
      
    };
    
    for(let i=0;i<metadatas.length;i+=2){
      let key = metadatas[i].value;
      let value = metadatas[i + 1].value;
      
      metadata={
        ...metadata,
        [key]:value
      }
      
      // for (let j = 0; j < dicts.length; j += 2) {
      //   let dictkey = dicts[j].value;
      //   let dictValue = dicts[j + 1].value;
      //   // let obj = undefined;
      //   // if (dictkey === "frame" || dictkey === "sourceColorRect") {
      //   //   let c = dictValue.match(reg);
      //   //   obj = {
      //   //     x: parseInt(c[0]),
      //   //     y: parseInt(c[1]),
      //   //     w: parseInt(c[2]),
      //   //     h: parseInt(c[3]),
      //   //   };
      //   // } else if (dictkey === "offset") {
      //   //   let c = dictValue.match(reg);
      //   //   obj = {
      //   //     x: parseInt(c[0]),
      //   //     y: parseInt(c[1]),
      //   //   };
      //   // } else if (dictkey === "sourceSize") {
      //   //   let c = dictValue.match(reg);
      //   //   obj = {
      //   //     w: parseInt(c[0]),
      //   //     h: parseInt(c[1]),
      //   //   };
      //   // } else if (dictkey === "rotated") {
      //   //   obj = dictValue === "false" ? false : true;
      //   // } else {
      //   //   obj = dictValue;
      //   // }

      //   metadata = {
      //     ...metadata,
      //     [dictkey]: dictValue,
      //   };
      // }
     
    }


    return {
      list: plistArray,
      metadata
    };
  }
  static onGenerate(fileName, list,image) {
    let frameData = [];

    list.forEach((plist) => {
      let keyItem = `
<key>${plist.key}</key>
<dict>
  <key>frame</key>
              <string>{{${plist.frame.x},${plist.frame.y}},{${plist.frame.w},${plist.frame.h}}}</string>
              <key>offset</key>
              <string>{${plist.offset.x},${plist.offset.y}}</string>
              <key>rotated</key>
              <false/>
              <key>sourceColorRect</key>
              <string>{{${plist.sourceColorRect.x},${plist.sourceColorRect.y}},{${plist.sourceColorRect.w},${plist.sourceColorRect.h}}}</string>
              <key>sourceSize</key>
              <string>{${plist.sourceSize.w},${plist.sourceSize.h}}</string>
</dict>
`;
      frameData.push(keyItem);
    });

    let size = `{${image.width},${image.height}}`;

    let template = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>frames</key>
<dict>
${frameData.join("")}
</dict>
<key>metadata</key>
<dict>
<key>format</key>
<integer>2</integer>
<key>realTextureFileName</key>
<string>${fileName}</string>
<key>size</key>
<string>${size}</string>
<key>textureFileName</key>
<string>${fileName}</string>
</dict>
</dict>
</plist>`;
    return template;

    // console.log(template);

    // var a = document.getElementById("generate-file");

    // var file = new Blob([template], { type: "text/plain" });
    // a.href = URL.createObjectURL(file);

    // const newName = fileName.split(".");

    // a.download = newName[0] + ".plist";
    // a.dispatchEvent(
    //   new MouseEvent("click", { bubbles: false, cancelable: true })
    // );
  }

  static reader2Text(text) {
    return new PlistReader(text);
  }
}
